using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using PropertyExpression.ControllableQuery;
using PropertyExpression.ControllableQuery.Test;
using PropertyExpression.ControllableQuery.TypedReader;

namespace ConsoleApplication3
{
    public static class QExecutor
    {
        public static IEnumerable<TRecordset> MaterializeReader<TParams, TRecordset>(
            Func<SqlCommand, TParams> paramsFunc, Func<TParams, IQuery<TRecordset>> recordsetFunc)
        {
            return MaterializeReader(context => recordsetFunc(paramsFunc(context)));
        }

        public static IEnumerable<TRecordset> MaterializeReader<TRecordset>(
            Func<SqlCommand, IQuery<TRecordset>> recordsetFunc)
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                connection.Open();
                using (var sqlCommand = new SqlCommand())
                {
                    sqlCommand.Connection = connection;
                    var query = recordsetFunc(sqlCommand);
                    sqlCommand.CommandText = query.TransformText();
                    using (var sqlDataReader = sqlCommand.ExecuteReader())
                        while (sqlDataReader.Read())
                            yield return query.GetReader(sqlDataReader).Materialize();
                }
            }
        }


        public static void ExecuteNonQuery<TParams>(
            Func<SqlCommand, TParams> paramsFunc, Func<TParams, INonQuery> recordsetFunc)
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                connection.Open();
                using (var sqlCommand = new SqlCommand())
                {
                    sqlCommand.Connection = connection;
                    var query = recordsetFunc(paramsFunc(sqlCommand));
                    sqlCommand.CommandText = query.TransformText();
                    sqlCommand.ExecuteNonQuery();
                }
            }
        }

        public static void ExecuteNonQuery(
            Func<INonQuery> recordsetFunc)
        {
            ExecuteNonQuery(context => new {}, p => recordsetFunc());
        }

        public static string ConnectionString
        {
            get { return @"Data Source=(local);Initial Catalog=ControllableQuery;Integrated Security=True"; }
        }
    }
}